package com.mask.sca.auth.service.impl;

import com.mask.sca.auth.service.AuthService;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.exceptions.InvalidClientException;
import org.springframework.security.oauth2.provider.*;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

@Service
public class AuthServiceImpl implements AuthService {

    private final AuthenticationManager authenticationManager;
    private final ClientDetailsService clientDetailsService;
    private final AuthorizationServerTokenServices tokenServices;

    @Resource
    private PasswordEncoder passwordEncoder;

    public AuthServiceImpl(AuthenticationManager authenticationManager,
                           ClientDetailsService clientDetailsService,
                           AuthorizationServerTokenServices tokenServices) {
        this.authenticationManager = authenticationManager;
        this.clientDetailsService = clientDetailsService;
        this.tokenServices = tokenServices;
    }

    @Override
    public Map<String, Object> passwordLogin(String username, String password,String loginType,
                                             String clientId, String clientSecret) {
        //验证客户端信息
        validateClient(clientId, clientSecret);

        //验证用户名密码
        Authentication authentication = authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(username+":"+loginType, password)
        );

        //生成 Token
        return generateToken(authentication, clientId);
    }

    @Override
    public Map<String, Object> smsCodeLogin(String mobile, String code,
                                            String clientId, String clientSecret) {
        validateClient(clientId, clientSecret);

        // 验证短信验证码
        if (!verifySmsCode(mobile, code)) {
            throw new IllegalArgumentException("Invalid SMS code");
        }
        // 通过手机号获取用户信息
        String username = loadUsernameByMobile(mobile);

        // 调用密码登录逻辑
        return passwordLogin(username, null,null, clientId, clientSecret);
    }

    @Override
    public Map<String, Object> refreshToken(String refreshToken,
                                            String clientId, String clientSecret) {
        validateClient(clientId, clientSecret);

        // 刷新 Token
        TokenRequest tokenRequest = new TokenRequest(
                new HashMap<>(),
                clientId,
                clientDetailsService.loadClientByClientId(clientId).getScope(),
                "refresh_token"
        );

        OAuth2AccessToken accessToken = tokenServices.refreshAccessToken(
                refreshToken,
                tokenRequest
        );

        return convertTokenToMap(accessToken);
    }

    // 验证客户端信息
    private void validateClient(String clientId, String clientSecret) {
        ClientDetails clientDetails = clientDetailsService.loadClientByClientId(clientId);
        // 验证客户端密钥（注意：配置中已加密，需用 passwordEncoder 匹配）
        if (!passwordEncoder.matches(clientSecret, clientDetails.getClientSecret())) {
            throw new InvalidClientException("客户端密钥错误");
        }
    }

    // 生成 Token
    private Map<String, Object> generateToken(Authentication authentication, String clientId) {
        ClientDetails clientDetails = clientDetailsService.loadClientByClientId(clientId);

        TokenRequest tokenRequest = new TokenRequest(
                new HashMap<>(),
                clientId,
                clientDetails.getScope(),
                "password"
        );

        OAuth2Request oAuth2Request = tokenRequest.createOAuth2Request(clientDetails);
        OAuth2Authentication oAuth2Authentication = new OAuth2Authentication(oAuth2Request, authentication);

        OAuth2AccessToken accessToken = tokenServices.createAccessToken(oAuth2Authentication);

        return convertTokenToMap(accessToken);
    }
    /**
     * 将 OAuth2AccessToken 转换为 Map
     */
    private Map<String, Object> convertTokenToMap(OAuth2AccessToken token) {
        Map<String, Object> result = new HashMap<>();
        result.put("access_token", token.getValue());
        result.put("token_type", token.getTokenType());
        result.put("expires_in", token.getExpiresIn());

        if (token.getRefreshToken() != null) {
            result.put("refresh_token", token.getRefreshToken().getValue());
        }

        // 添加额外信息（如用户ID、角色等）
        if (token instanceof DefaultOAuth2AccessToken) {
            DefaultOAuth2AccessToken defaultToken = (DefaultOAuth2AccessToken) token;
            Map<String, Object> additionalInfo = defaultToken.getAdditionalInformation();
            if (!additionalInfo.isEmpty()) {
                result.putAll(additionalInfo);
            }
        }

        return result;
    }

    /**
     * 验证短信验证码
     */
    private boolean verifySmsCode(String mobile, String code) {
        // 实际项目中应调用短信服务验证
        // 这里使用简化实现，实际应从缓存或数据库获取验证码
//        return smsCodeService.validateSmsCode(mobile, code);
        return false;
    }

    /**
     * 通过手机号加载用户名
     */
    private String loadUsernameByMobile(String mobile) {
        // 从数据库查询用户
//        User user = userRepository.findByMobile(mobile)
//                .orElseThrow(() -> new UsernameNotFoundException("User not found for mobile: " + mobile));

//        return user.getUsername(); // 返回用户名（或使用手机号作为用户名）
        return null;
    }
}